#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<hs/hs.h>

// 函数原型
// 匹配回调函数
static int on_match(unsigned int id, unsigned long long from,
        unsigned long long to, unsigned int flags, void *ctx);
void check_phone_num(const char * num, int *flag);

int main()
{
    int i;
    int flag;
    char *s[] = {"029-849-1249", "1-885-1202", "876-9182",
                 "1923-989-2912", "0591-089-2126", "021-29-8932",
                 "9280-9981", "910-92817", "01-9A9-8712",
                 "298491249", "0086-010-102-9182",
                 "A09-021-928-1921", "123-1211", "29-1+983"};

    for(i = 0; i < sizeof(s) / sizeof(s[0]); i++)
    {
        flag = 0;
        check_phone_num(s[i], &flag);
        if(flag)
        {
            printf("%s is valid phonenum.\n", s[i]);
        }
        else
        {
            printf("%s is not valid phonenum.\n", s[i]);
        }
    }

    return 0;
}

// 判断电话号码有效性
void check_phone_num(const char *num, int *flag)
{
    const char *pat = "^(([0-9]{0,4})-)?[1-9][0-9]{2}-[0-9]{4}$";

    // 正则对象指针
    hs_database_t *db = NULL;
    hs_compile_error_t *compile_err = NULL;

    // 编译正则表达式
    if(hs_compile(pat, HS_FLAG_DOTALL, HS_MODE_BLOCK, NULL,
                  &db, &compile_err) != HS_SUCCESS)
    {
        fprintf(stderr, "ERROR: Unable to compile pattern \"%s\": %s\n",
                pat, compile_err->message);
        hs_free_compile_error(compile_err);
        exit(EXIT_FAILURE);
    }

    // 申请临时空间
    hs_scratch_t *scratch = NULL;
    if(hs_alloc_scratch(db, &scratch) != HS_SUCCESS)
    {
        fprintf(stderr, "ERROR: Unable to allocate scratch space."
                        " Exiting.\n");
        hs_free_database(db);
        exit(EXIT_FAILURE);
    }

    // 正则匹配
    if(hs_scan(db, num, strlen(num), 0, scratch, on_match, flag)
            != HS_SUCCESS)
    {
        fprintf(stderr, "ERROR: Unable to scan input buffer. Exiting.\n");
        hs_free_scratch(scratch);
        hs_free_database(db);
        exit(EXIT_FAILURE);
    }

    // 释放空间
    hs_free_scratch(scratch);
    hs_free_database(db);
}

static int on_match(unsigned int id, unsigned long long from,
        unsigned long long to, unsigned int flags, void *ctx)
{
    int *tmp = (int *)ctx;

    *tmp = 1;

    return 0; // 返回0继续匹配，返回1结束匹配
}
